package com.example.design.nioandnettty.主从Reactor多线程;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * 主reactor只处理Accept事件
 */
public class GroupChatServer {
    //定义属性
    private Selector selector;
    private ServerSocketChannel listenChannel;
    private static final int PORT = 6667;
    private SubReactor subReactor;

    //构造器
    //初始化工作
    public GroupChatServer() {
        try {
            //得到选择器
            selector = Selector.open();
            //ServerSocketChannel
            listenChannel = ServerSocketChannel.open();
            //绑定端口
            listenChannel.socket().bind(new InetSocketAddress(PORT));
            //设置非阻塞模式
            listenChannel.configureBlocking(false);
            //将该listenChannel 注册到selector,主reactor只处理Accept事件
            listenChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //监听
    public void listen() {
        System.out.println("监听线程主reactor: " + Thread.currentThread().getName());
        System.out.println("-----------------------------------------------------------");
        try {
            //循环处理
            while (true) {
                int count = selector.select();
                if (count > 0) {
                    //有事件处理
                    //遍历得到selectionKey 集合
                    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        //取出selectionkey
                        SelectionKey key = iterator.next();

                        //监听到accept; 主reactor只处理Accept事件
                        if (key.isAcceptable()) {
                            //主Reactor监听
                            SocketChannel sc = listenChannel.accept();
                            sc.configureBlocking(false);
                            //提示
                            System.out.println(sc.getRemoteAddress() + " 上线 ");
                            System.out.println("-----------------------------------------------------------");
                            /**
                             * 主Reactor只关心Accept事件
                             */
                            if (subReactor == null) {
                                Selector selector = key.selector();
                                SelectionKey sk = sc.register(selector, SelectionKey.OP_READ);
                            } else {
                                // 从主reactor：将主Reactor中的Channel注册到从Reactor中的selector, 并监听监听read,write事件
                                subReactor.register(sc);
                            }
                        }
                        //当前的key 删除，防止重复处理
                        iterator.remove();
                    }
                } else {
                    System.out.println("等待....");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            //发生异常处理....

        }
    }

    /**
     * 添加子Reactor并执行
     *
     * @param subReactor
     * @return
     */
    public void addSub(SubReactor subReactor) {
        this.subReactor = subReactor;
        this.subReactor.run();
    }


    public static void main(String[] args) {
        //创建服务器对象
        GroupChatServer groupChatServer = new GroupChatServer();
        groupChatServer.addSub(new SubReactor());
        groupChatServer.listen();
    }
}

//可以写一个Handler
class MyHandler {
    public void readData() {

    }

    public void sendInfoToOtherClients() {

    }
}

